#ifndef RING_H
#define RING_H

#include <assert.h>

/*! \brief The Ring struct */
struct Ring
{
    /*! \brief lenght of the ring */
    int lenght;
    /*! \brief offset between the processor number and the ring rank */
    int offset;

    /*! \brief operator [] return the processor number at the ring rank passed in argument */
    inline int operator [] (int rank) const {
        assert((rank >= 0) && (rank < lenght));
        return rank + offset;
    }

    /*! \brief next return the next processor in the ring */
    inline int next(int rank) const {
        assert((rank >= 0) && (rank < lenght));
        return offset + ((rank + 1) % lenght);
    }

    /*! \brief previous return the previous processor in the ring */
    inline int previous(int rank) const {
        assert((rank >= 0) && (rank < lenght));
        int mod = (rank - 1) % lenght;
        return offset + ((mod >= 0) ? mod : lenght + mod);
    }

    /*! \brief return the ring rank of the processor number passed in argument */
    inline int rank(int id) const {
        int ret = id - offset;
        assert((ret >= 0) && (ret < lenght));
        return ret;
    }
};

#endif // RING_H
